package com.zhongfl.crm.service.impl.boss;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.zhongfl.crm.common.BossConsts;
import com.zhongfl.crm.enums.boss.CommonLogType;
import com.zhongfl.crm.enums.boss.OrderStatus;
import com.zhongfl.crm.enums.boss.OrderTaskLogType;
import com.zhongfl.crm.exception.CRMException;
import com.zhongfl.crm.lixiao.mapper.CustomerOrderMapper;
import com.zhongfl.crm.lixiao.mapper.OrderMapper;
import com.zhongfl.crm.lixiao.mapper.OrderTaskLogMapper;
import com.zhongfl.crm.model.boss.*;
import com.zhongfl.crm.service.boss.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tech.heptagram.channel.api.common.AssertUtils;
import tech.heptagram.core.common.util.JsonUtil;

import javax.annotation.Resource;
import java.util.Comparator;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * CustomerOrderServiceImpl 客户订单 服务实现类
 *
 * @author tiantian
 * @date 2018/8/20 18:17
 */
@Service
@Slf4j
public class CustomerOrderServiceImpl implements CustomerOrderService {
    @Resource
    private CustomerOrderMapper customerOrderMapper;
    @Resource
    private SequenceService sequenceService;
    @Resource
    private AmibaStaffService amibaStaffService;
    @Resource
    private OrderMapper deliveryOrderMapper;
    @Resource
    private OrderTaskLogMapper orderTaskLogMapper;
    @Resource
    private CommonLogService commonLogService;
    @Resource
    private OrderMemorandumService orderMemorandumService;
    @Resource
    private OrderService orderService;

    @Resource
    private AmibaService amibaService;

    @Override
    public void updateByCustomerOrderNo(CustomerOrder updateInfo) {
        AssertUtils.notNull(updateInfo, "客户订单为空!");
        AssertUtils.notNull(updateInfo.getCustomerOrderNo(), "客户订单号为空!");
        CustomerOrder oldOrder = customerOrderMapper.selectByCustomerOrderNo(updateInfo.getCustomerOrderNo());

        customerOrderMapper.updateByCustomerOrderNoSelective(updateInfo);

        try {
            commonLogService.addWithFieldMeta(CommonLogType.CUSTOMER_ORDER,
                    CommonLogType.CUSTOMER_ORDER_MODIFY,
                    updateInfo.getCustomerOrderNo(),
                    oldOrder,
                    updateInfo,
                    updateInfo.getUpdatedBy()
            );
        } catch (Exception e) {
            throw new CRMException("添加操作日志失败", e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String saveCustomerOrder(CustomerOrder saveInfo) {
        AssertUtils.notNull(saveInfo, "保存对象为空！");
        // 1. 订单号
        String orderNo = sequenceService.generateCustomerOrderNo();
        saveInfo.setCustomerOrderNo(orderNo);
        // 2. 商务经理
        //List<AmibaStaff> salesmanLists = amibaStaffService.findByStaffCode(saveInfo.getBusinessManagerStaffCode());
        //if (CollectionUtils.isEmpty(salesmanLists)) {
        //    throw new WorkOrderException("商务经理: " + saveInfo.getBusinessManagerStaffName() + "(" + saveInfo.getBusinessManagerStaffCode() + ")不存在");
        //}
        //AmibaStaff manager = salesmanLists.get(0);
        //saveInfo.setBusinessManagerStaffName(manager.getStaffName());
        //// 3.商务助理
        //AmibaStaff assistant;
        //if (StringUtils.isNotEmpty(saveInfo.getBusinessAssistantStaffCode())) {
        //    assistant = amibaStaffService.findSingleByStaffCode(saveInfo.getBusinessAssistantStaffCode());
        //    if (Objects.nonNull(assistant)) {
        //        saveInfo.setBusinessAssistantStaffName(assistant.getStaffName());
        //        saveInfo.setBusinessAssistantStaffMobile(assistant.getStaffMobile());
        //    }
        //} else {
        //    saveInfo.setBusinessAssistantStaffName(manager.getStaffName());
        //    saveInfo.setBusinessAssistantStaffMobile(manager.getStaffMobile());
        //}
        customerOrderMapper.insertSelective(saveInfo);

        try {
            commonLogService.add(CommonLogType.CUSTOMER_ORDER, CommonLogType.CUSTOMER_ORDER_ADD, orderNo, "客户订单已提交", saveInfo.getCreatedBy());
        } catch (Exception e) {
            throw new CRMException("创建初始化日志失败", e);
        }

        OrderMemorandum orderMemorandum = new OrderMemorandum();
        orderMemorandum.setOrderNo(orderNo);
        orderMemorandum.setCustomerOrderNo(orderNo);
        orderMemorandum.setStaffName(BossConsts.BossSystem.NAME);
        orderMemorandum.setContent("新增客户订单 " + saveInfo.getCustomerName());
        orderMemorandum.setModifiedBy(BossConsts.BossSystem.NAME);
        orderMemorandum.setAvatarUrl(BossConsts.BossSystem.AVATAR_URL);
        orderMemorandumService.saveCustomerOrderSystemLog(orderMemorandum);

        //todo 添加商务经理为协作人，考虑从这里开始协作人表要添加订单类型列

        return orderNo;
    }

    @Override
    public void cancelCustomerOrder(String customerOrderNo, String staffName) {
        AssertUtils.notNull(customerOrderNo, "客户订单号为空！");
        CustomerOrder customerOrder = customerOrderMapper.selectByCustomerOrderNo(customerOrderNo);

        customerOrderMapper.cancelCustomerOrder(customerOrderNo);

        try {
            commonLogService.add(CommonLogType.CUSTOMER_ORDER,
                    CommonLogType.CUSTOMER_ORDER_STATUS_CHANGE,
                    customerOrderNo,
                    "客户订单状态由[" + customerOrder.getCustomerOrderStatusName() + "]变为[已取消]",
                    staffName);
        } catch (Exception e) {
            throw new CRMException("添加操作日志失败", e);
        }

        // 客户订单取消后，把所有交付订单取消掉
        List<Order> deliveryOrders = orderService.findListByCustomerOrderNo(customerOrderNo);
        deliveryOrders.stream()
                .filter(order -> !OrderStatus.STATUS_CANCEL.equals(order.getStatus()))
                .forEach(order -> orderService.cancelOrder(order.getOrderNo(),customerOrder.getBusinessManagerStaffName(),customerOrder.getBusinessManagerStaffCode()));

    }

    private boolean validateUpdate(String customerOrderNo) {
        if (StringUtils.isEmpty(customerOrderNo)) {
            return false;
        }

        CustomerOrder customerOrder = customerOrderMapper.selectByCustomerOrderNo(customerOrderNo);
        if (Objects.isNull(customerOrder)) {
            return false;
        }

        if (OrderStatus.STATUS_CANCEL.name().equals(customerOrder.getLatestDeliveryOrderStatus())) {
            return false;
        }
        if (OrderStatus.STATUS_COMPLETED.name().equals(customerOrder.getLatestDeliveryOrderStatus())) {
            return false;
        }

        return true;
    }

    private void updateCustomerOrder(Order order, String staffCode, String staffName) throws JsonProcessingException {
        CustomerOrder oldCustomerOrder = customerOrderMapper.selectByCustomerOrderNo(order.getCustomerOrderNo());

        CustomerOrder updateInfo = new CustomerOrder();
        updateInfo.setCustomerOrderNo(order.getCustomerOrderNo());
        updateInfo.setCustomerName(order.getName());
        updateInfo.setLoanAmount(order.getLoanAmount());
        updateInfo.setLoanDuration(order.getLoanDuration());
        updateInfo.setCustomerOrderStatus(order.getStatus().name());

        updateInfo.setLatestDeliveryOrderStatus(order.getStatus().name());
        updateInfo.setLatestDeliveryOrderNo(order.getOrderNo());

        updateInfo.setUpdatedBy(staffName);

        customerOrderMapper.updateByCustomerOrderNoSelective(updateInfo);

        try {
            commonLogService.addWithFieldMeta(CommonLogType.CUSTOMER_ORDER,
                    CommonLogType.CUSTOMER_ORDER_MODIFY,
                    updateInfo.getCustomerOrderNo(),
                    oldCustomerOrder,
                    updateInfo,
                    updateInfo.getUpdatedBy());
        } catch (Exception e) {
            throw new CRMException("添加操作日志失败", e);
        }

        addOrderTaskLog(updateInfo, staffCode, staffName);
    }

    private void addOrderTaskLog(CustomerOrder customerOrder, String staffCode, String staffName) throws JsonProcessingException {
        OrderTaskLog orderTaskLog = new OrderTaskLog();

        CustomerOrder currentCustomerOrder = findCustomerOrderByCustomerOrderNo(customerOrder.getCustomerOrderNo());
        customerOrder.setLxCustomerOrderId(currentCustomerOrder.getLxCustomerOrderId());
        customerOrder.setChannelId(currentCustomerOrder.getChannelId());
        customerOrder.setChannelName(currentCustomerOrder.getChannelName());

        orderTaskLog.setOrderNo(customerOrder.getCustomerOrderNo());
        orderTaskLog.setType(OrderTaskLogType.CUSTOMER_INFORMATION_CHANGE);
        orderTaskLog.setStaffCode(staffCode);
        orderTaskLog.setModifiedBy(staffName);
        orderTaskLog.setContent(JsonUtil.toJson(customerOrder));

        orderTaskLogMapper.insertSelective(orderTaskLog);
    }

    private Order getFastestDeliveryOrder(List<Order> collect) {
        if (CollectionUtils.isEmpty(collect)) {
            return null;
        }

        // 这里默认的是返回第一个最大值记录
        Order fastestDeliveryOrder = collect.stream().max(Comparator.comparing(order -> order.getStatus().getIndex())).get();

        return fastestDeliveryOrder;
    }

    /**
     * 更新客户订单信息逻辑：
     * 1.判断是否符合更新条件
     * 1.1 客户订单号为空，返回
     * 1.2 客户订单不存在，返回
     * 1.3 客户订单已取消，返回
     * 1.4 客户订单已完成，返回
     * 2.查找交付订单，进行更新
     * 2.1 排除已取消的交付订单，如果为空，返回
     * 2.2 如果剩下一个，
     *     状态和交付订单状态一样，不修改
     *     状态不一样，则更新该订单所有信息到客户订单
     * 2.3 如果有多个人，
     *     状态和交付订单状态一样，不修改
     *     状态不一样，则更新该订单状态到客户订单
     *
     * @param customerOrderNo 客户订单号
     * @param staffCode       操作人员工号
     * @param staffName       操作人姓名
     */
    @Override
    public void updateCustomerOrderFromDeliveryOrder(String customerOrderNo, String staffCode, String staffName) {
        if (!validateUpdate(customerOrderNo)) {
            return;
        }

        List<Order> deliveryOrders = deliveryOrderMapper.findByCustomerOrderNo(customerOrderNo);

        List<Order> deliveryOrdersWithoutCancel = deliveryOrders.stream().filter(s -> !OrderStatus.STATUS_CANCEL.equals(s.getStatus())).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(deliveryOrdersWithoutCancel)) {
            //cancelCustomerOrder(customerOrderNo,staffName);
            return;
        }

        CustomerOrder customerOrder = customerOrderMapper.selectByCustomerOrderNo(customerOrderNo);

        if (deliveryOrdersWithoutCancel.size() == 1) {
            Order order = deliveryOrdersWithoutCancel.get(0);
            if(customerOrder.getCustomerOrderStatus().equals(order.getStatus().name())){
                return;
            }

            try {
                updateCustomerOrder(deliveryOrdersWithoutCancel.get(0), staffCode, staffName);
            } catch (JsonProcessingException e) {
                log.error(e.getMessage());
            }
            return;
        }

        Order order = getFastestDeliveryOrder(deliveryOrdersWithoutCancel);
        if (Objects.isNull(order)) {
            log.error("客户订单号：" + customerOrderNo + ",未找到可用来更新的交付订单!");
            return;
        }
        if(customerOrder.getCustomerOrderStatus().equals(order.getStatus().name())){
            return;
        }
        try {
            updateCustomerOrder(order, staffCode, staffName);
        } catch (JsonProcessingException e) {
            log.error(e.getMessage());
        }
    }

    @Override
    public CustomerOrder findCustomerOrderByCustomerOrderNo(String customerOrderNo) {
        AssertUtils.notNull(customerOrderNo, "客户订单号为空！");
        CustomerOrder customerOrder = customerOrderMapper.selectByCustomerOrderNo(customerOrderNo);
        if(Objects.nonNull(customerOrder.getBusinessManagerAmibaId())) {
            Amiba businessAmiba = amibaService.findById(customerOrder.getBusinessManagerAmibaId());
            if(Objects.nonNull(businessAmiba)){
                customerOrder.setBusinessManagerAmibaName(businessAmiba.getName());
            }
        }
        return customerOrder;
    }
}
